
package ija.xls.notation.specific;

import ija.xls.notation.DeskCoordinate;
import ija.xls.notation.GameMove;
import ija.xls.notation.NotationReader;
import ija.xls.notation.types.GameOperation;

/**
 * Třída pro načítání tahu určeného konkrétní textovou notaci dle zadání IJA
 * @author Radek Necas, xnecas18
 */
public class IjaNotationReader implements NotationReader {

    // Soukromé konstanty pro stavy při překládání
    private final int NULL = 0;
    private final int POS1COL = 1;
    private final int POS1ROW = 2;
    private final int OP = 3;
    private final int POS2COL = 4;
    private final int POS2ROW = 5;
    
    public IjaNotationReader () {       
    }

    @Override
    public GameMove translate(String notation) {
        if(notation == null)
            return null;
        
        String n = notation.toLowerCase();
        GameOperation op = GameOperation.NOP;
        char c;
        int hasRead = NULL;
        char p1Col = '\0';
        int p1Row = 0;
        char p2Col = '\0';
        int p2Row = 0;
        
        // Projdu cely retezec
        for(int i = 0; i < n.length(); i++) {
            c = n.charAt(i);
            // Pokud jde o mezeru preskakuju ji
            if(Character.isWhitespace(c))
                continue;
            
            // Statovy automat, dle toho co jsem z retezce jiz precetl
            switch(hasRead) {
            
                // Pokud jsem na zacatku nebo jsem jiz precetl operaci
                case NULL:
                case OP:
                    if(Character.isLetter(c)) {
                        if(hasRead == NULL) {
                            p1Col = c;
                            hasRead = POS1COL;
                        }
                        else {
                            p2Col = c;
                            hasRead = POS2COL;
                        }
                    }
                    else
                        return null;
                    
                    break;
                    
                // Pokud jsem precetl sloupec prvni ci druhe pozice
                case POS1COL:
                case POS2COL:
                    if(Character.isDigit(c)) {
                        if(hasRead == POS1COL) {
                            p1Row = (int)(c - '0');
                            hasRead = POS1ROW;
                        }
                        else {
                            p2Row = (int)(c - '0');
                            hasRead = POS2ROW;
                        }
                    }
                    else {
                        return null;
                    }
                    
                    break;
                    
                // Pokud jsem precetl radek prvni ci druhe pozice
                case POS1ROW:
                    if(c == '-') {
                        op = GameOperation.MOVE;
                        hasRead = OP;
                    }
                    else if (c == 'x') {
                        op = GameOperation.JUMP;
                        hasRead = OP;
                    }
                    else
                        return null;
                    
                    break;
             
                // Za id radku druhe pozice jiz nesmi nic byt (bile znaky preskoceny)
                case POS2ROW:
                    return null;
                    
                // Default by nemel nikdy nastat
                default:
                    return null;
            }   // end switch(hasRead)
        }   // end for(string)
        
        if(hasRead == POS2ROW)
            return new GameMove(new DeskCoordinate(p1Col, p1Row), op, new DeskCoordinate(p2Col, p2Row));
        
        return null;          
    }
}
